<?php
/**
* A model class for encapsulating business entities + their business logic
* 
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* 
* @copyright Copyright (c) 2008-2009 Ne8, LLC <josh.ribakoff@gmail.com>
* @license New BSD License
* @version 0.1
* @category Shuffler
* @package Shuffler_Model
*/
abstract class Shuffler_Model
{
    /**
    * @var integer id of this model
    */
    private $id = 0;
    
    /**
    * @var string title
    */
    protected $title; 
    
    protected $idObservers = array();
    
    /**
    * Create the model
    * 
    * @param integer optional id of the model, defaults to 0
    */
    public function __construct( $id = null )
    {
        if( is_null( $id ) )
        {
            $id = 0;
        }
        $this->id = $id;
        $this->init();
    }
    
    /**
    * Template method
    */
    protected function init() { }
    
    /**
    * Get ID for the model
    * 
    * @return integer ID of this model, 0 if none created yet
    */
    public function getId()
    {
        return $this->id;
    } 
    
    public function setId( $id )
    {
        if( $this->id > 0 )
        {
            throw new Exception( 'Cannot change immutable ID' );
        }
        $this->id = $id;
        foreach( $this->idObservers as $observer )
        {
            $observer->notify( $this );
        }
    } 
    
    public function addIdObserver( Shuffler_Model_IdObserver $observer )
    {
        array_push( $this->idObservers, $observer );
    }
   
   /**
    * Get a data mapper
    * 
    * @param string name of model to find mapper for, defaults to current class
    * @return Shuffler_Mapper
    * 
    * @todo should be handled with seperated interface
    */
    public function getMapper( $modelName = '' )
    {
        $modelName = $modelName ? $modelName : get_class( $this );
        $modelName = str_replace( '_Null', '', $modelName );
        return Shuffler_Factory::getInstance()->getMapper( $modelName );    
    }
    
    /**
    * Checks if this model equals another 
    * 
    * @param Shuffler_Model model to compare with
    * @return boolean
    */
    public function equals( Shuffler_Model $model )
    {
        if( $model === $this )
        {
            return true;
        }
        $class = get_class( $this );
        if(
            !( $model instanceof $class )
            &&
            !( $model instanceof Shuffler_Null )
            &&
            !( $this instanceof Shuffler_Null )
        )
        {
            return false;
        }
        if
        (
            // If both models have no ID
            $this->getId() == 0 && $model->getId() == 0 &&
            // and If both models have getTitle() methods
            method_exists( $this, 'getTitle' ) && method_exists( $model, 'getTitle' ) &&
            // and if both models have a title
            strlen( $this->getTitle() ) > 0 && strlen( $model->getTitle() ) > 0 &&
            // and if the titles are the same
            $this->getTitle() === $model->getTitle()
        )
        {
            return true;
        }
        if( $this->getId() == 0 || $model->getId() == 0 )
        {                                                                 
            return false;
        }
        return $this->getId() === $model->getId();
    }
    
    public function getTitle()
    {
        return (string)$this->title;
    }
    
    /**
    * @param string
    * @return Shuffler_Model
    */
    public function setTitle( $title )
    {
        $this->title = $title;
        return $this;
    }   
    
    public function __toString()
    {
        return (string)$this->getTitle();
    }
    
}